/// <reference path="../jquery-1.4.1-vsdoc.js" />

(function ($) {


	$.fn.ShSelectList = function (method) {

		var settings = {
			headers: "rel",
			animate: true,
			animateevent: "click",
			multiple: false,
			maximumitems: 0,
			warningmessage: "You can only select {0} items", // TODO make from data.aspx
			itemseparator: ", ",
			hideloading: false,
			defaultstate: "show",
			changetext: "change selection",
			onchange: null
		};

		var methods = {
			init: function (settingoptions) {
				if (settingoptions) {
					$.extend(settings, settingoptions);
				}
				return this.each(function () {

					var $this = $(this),
					 data = $this.data('sh.selectlist');

					// If the plugin hasn't been initialized yet
					if (!data) {

						var selectedTextArr = [],
							selectedText = '',
							selectedValue = $this.val(),
							optgroups = $this.children("optgroup"),
							options;
						var buildItem = function ($t, isSelected) {

							return '<li data-index="{0}" data-value="{1}"{3}>{2}</li>'
									.replace("{0}", $t.index())
									.replace("{1}", $t.val())
									.replace("{2}", $t.text())
									.replace("{3}", (isSelected) ? ' class="selected"' : '');

						};
						// the div with selected value + ul
						var replacementHtml = '<div class="selectedElement"></div><ul class="{0}">'
								.replace("{0}", $this.attr("class")); // transfer class to major ul

						var header = "";


						// If optgroups exist, use them rather than attributes

						if (optgroups.length > 0) {


							for (var og = 0; og < optgroups.length; og++) {
								header = optgroups.eq(og).attr("label");
								options = optgroups.eq(og).children("option");


								replacementHtml += '<li>' + header;
								replacementHtml += '<ul>';
								var tabindex = "0";
								if (settings.animate) {
									tabindex = "-1";
								}

								for (i = 0; i < options.length; i++) {
									var $t = $(options[i]),
									isSelected = $t.is("[selected]");

									replacementHtml += buildItem($t, isSelected);
									if (isSelected) selectedTextArr.push($t.text());
								}

								replacementHtml += '</ul>';
								replacementHtml += '</li>'; // close header li
							}


						} else {

							options = $this.children("option");

							for (i = 0; i < options.length; i++) {
								var $t = $(options[i]),
									isSelected = $t.is("[selected]");

								replacementHtml += buildItem($t, isSelected);
								if (isSelected) selectedTextArr.push($t.text());
							}


						}
						replacementHtml += '</ul></div>';
						var $newcontent = $(replacementHtml).insertAfter($this),
							$ul = $newcontent.filter("ul"),
							$selectedElement = $newcontent.first("div");


						$this.hide();

						if (selectedTextArr.length > 0)
							$selectedElement.text(selectedTextArr.join(settings.itemseparator));
						else
							$selectedElement.hide();




						// Event handler for selection click
						$ul.find("li").click(function (e) {
							var $item = $(this);

							var thisValue = $item.attr("data-value"),
								$selectedItems = $ul.find("li.selected");

							if (!settings.multiple) {
								// If this isn't a multi select, remove any other current item
								$selectedItems.removeClass("selected");
							}

							if ($item.hasClass("selected") && settings.multiple) {
								// This is a de-select on a multiple select
								$item.removeClass("selected");
							} else {
								// Set selected class on item
								$item.addClass("selected");
							}

							if (settings.animate && !settings.multiple) {
								$ul.slideUp("fast");
							}
							// reset selected text
							selectedTextArr = [];

							// Remove all previous selections as we will re-add the current selections
							$this.children("option").remove();

							$selectedItems = $ul.find("li.selected");

							// Check number of selections
							if (settings.multiple && settings.maximumitems > 0) {

								if ($selectedItems.length > settings.maximumitems) {
									$item.removeClass("selected");
									// uggg ugly
									alert(settings.warningmessage.replace("{0}", settings.maximumitems));
								}
							}

							// Add all current selections
							$selectedItems.each(function () {
								var $t = $(this);
								$this.append('<option value="{0}" selected="true">{1}</option>'
								.replace("{0}", $t.attr("data-value"))
								.replace("{1}", $t.text()));

								selectedTextArr.push($t.text());

							});


							// Set span to show current selections
							if (selectedTextArr.length > 0)
								$selectedElement.text(selectedTextArr.join(settings.itemseparator)).show();
							else
								$selectedElement.hide();

							// now call external onchange, change context to current element, and pass event and select object
							if (settings.onchange) settings.onchange.call($item, e, $this);


							return false;
						});

						// if already selected do collapse, actually, let that be settingsurable
						if (settings.defaultstate !== "show") {

							$ul.hide();
						}
						// if no items selected, select the first by default

						// now bind onclick! to show
						$selectedElement.click(function () {
							$ul.slideDown("fast");
						});

						$this.data('sh.selectlist', {
							element: $ul,
							selectedElement: $selectedElement
						});
					}
				});
			},
			destroy: function () {
				// remove select element and anything created by it (this = jquery select object)

				var s = this.data("sh.selectlist");
				if (s) {
					s.element.remove();
					s.selectedElement.remove();
					this.remove();
				}
			}
		};

		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' + method + ' does not exist');
		}



	};


})(jQuery);

